#include "../file/config.h"
#include "../file/errlog.h"
#include "../render/renderer.h"
#include "../rsrc/shader_manager.h"
#include "../rsrc/bitmap_manager.h"
#include "inputlib.h"
#include <list>

using namespace std;

#ifndef TERRAGE_GAME_H_INCLUDED
#define TERRAGE_GAME_H_INCLUDED

namespace TerraGE {
    class Scene {
        protected:
            string name;
            void (*start)(void *);
            void (*close)(void *);
            void (*update)(void *, float);
            void (*draw)(void *);
        public:
            Scene() {
                name="";
                draw=start=close=NULL;
                update = NULL;
            }
            Scene(std::string nm, void (*st)(void *), void (*up)(void *, float), void (*dr)(void *), void (*cl)(void *)) {
                name = nm; start = st; update = up; draw = dr; close = cl;
            }
            void Start(void *t) {if (start != NULL)  (*start)(t);}
            void Draw(void *t)  {if (draw != NULL)   (*draw)(t);}
            void Update(void *t, float v){if (update != NULL) (*update)(t, v);}
            void Close(void *t) {if (close != NULL)  (*close)(t);}

            void Set_Name(string nm) {name=nm;}
            string Get_Name() {return name;}

            void Set_Start(void (*v)(void *))  {start = v; }
            void Set_Update(void (*v)(void *, float)) {update = v;}
            void Set_Draw(void (*v)(void *))   {draw = v;  }
            void Set_Close(void (*v)(void *))  {close = v; }
    };


    class Game {
        private:
            string name;
            Config *config_file;
            Log *log_file;
            list<Renderer *> renderer_list;
            list<Scene *> scene_list;

            Scene *actual_scene;
            Scene *next_scene;

            ALLEGRO_DISPLAY *display;
            ALLEGRO_TIMER *timer;
            ALLEGRO_EVENT_QUEUE *queue;

            Shader_Manager *shader_mg;
            Bitmap_Manager *bitmap_mg;

            double last_time;
            int fps;
            float timestep;
        public:
            Game(string nm);
            int Main(int argc, char *argv[]);
            int Setup(int argc, char *argv[]);

            void Set_Scene_List(list<Scene *> sc) {scene_list=sc;}

            bool Setup_Display();
            void Setup_Timer();
            void Reset_Delta();
            void Update_Delta();
            void Render();

            Renderer *Get_First_Renderer() {return (*renderer_list.begin());}

            Shader_Manager *Get_Shader_Manager() {return shader_mg;}
            Bitmap_Manager *Get_Bitmap_Manager() {return bitmap_mg;}

            void Set_Scene(std::string nm);

            ALLEGRO_DISPLAY *Get_Display() {return display;}
            Log *Get_Log() {return log_file;}
    };
};





#endif
